﻿//using CosenSecurity;
using Microsoft.Practices.EnterpriseLibrary.Data.Sql;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using Easy.Common;
using Easy.DAL;
using Easy.Model;
using Easy.Operation.Expression;

namespace Easy.Operation
{
    public class Core
    {
        private string EntityName;
        private EntityDAL EntityDal;
        public Core(string entityName)
        {
            EntityName = entityName;
            EntityDal = new EntityDAL(EntityName);
        }

        //表单获取字段专用
        public Dictionary<string, Field> GetFields(string ViewName = null)
        {
            Dictionary<string, Field> fields = new Dictionary<string, Field>();
            DataTable dt = EntityDal.GetAttributeMapData(ViewName);
            foreach (DataRow dr in dt.Rows)
            {
                Field field = new Field();
                if (!(dr["Name"] is DBNull))
                    field.Name = dr["Name"].ToString().ToLower();
                if (!(dr["DisplayName"] is DBNull))
                    field.DisplayName = dr["DisplayName"].ToString();
                if (!(dr["Type"] is DBNull))
                    field.Type = (FieldType)Enum.Parse(typeof(FieldType), dr["Type"].ToString());
                if (!(dr["Length"] is DBNull))
                    field.Length = dr["Length"].ToString();
                if (!(dr["IsNullable"] is DBNull))
                    field.IsNullable = dr["IsNullable"].ToString() == "True";
                if (!(dr["Cansearchable"] is DBNull))
                    field.Cansearchable = dr["Cansearchable"].ToString() == "True";
                if (!(dr["Format"] is DBNull))
                    field.Format = (FieldFormat)Enum.Parse(typeof(FieldFormat), dr["Format"].ToString());
                if (!(dr["LookupEntityName"] is DBNull))
                    field.LookupEntityName = dr["LookupEntityName"].ToString();
                if (!(dr["IsPrimaryAtt"] is DBNull))
                    field.IsPrimaryAtt = dr["IsPrimaryAtt"].ToString() == "True";

                if (!(dr["IsGlobalPicklist"] is DBNull))
                    field.IsGlobalPicklist = dr["IsGlobalPicklist"].ToString() == "True";
                if (!(dr["GlobalPicklist"] is DBNull))
                    field.GlobalPicklist = dr["GlobalPicklist"].ToString();
                if (!(dr["LookupPrimaryAtt"] is DBNull))
                    field.LookupPrimaryAtt = dr["LookupPrimaryAtt"].ToString();
                if (!(dr["AttributeWidth"] is DBNull))
                    field.AttributeWidth = dr["AttributeWidth"].ToString();
                if (!(dr["ViewOrderBy"] is DBNull))
                    field.ViewOrderBy = dr["ViewOrderBy"].ToString();
                fields.Add(field.Name, field);
            }
            return fields;
            
        }
        
        
        /// <summary>
        /// 获取视图中要显示的字段
        /// </summary>
        /// <param name="ViewName"></param>
        /// <returns></returns>
        public Dictionary<string, Field> GetViewFields(string ViewName)
        {

            Dictionary<string, Field> fields = new Dictionary<string, Field>();
            DataTable dt = EntityDal.GetViewAttMapData(ViewName);
            foreach (DataRow dr in dt.Rows)
            {
                Field field = new Field();
                if (!(dr["Name"] is DBNull))
                    field.Name = dr["Name"].ToString().ToLower();
                if (!(dr["DisplayName"] is DBNull))
                    field.DisplayName = dr["DisplayName"].ToString();
                if (!(dr["EntityName"] is DBNull))
                    field.EntityName = dr["EntityName"].ToString();
                if (!(dr["Type"] is DBNull))
                    field.Type = (FieldType)Enum.Parse(typeof(FieldType), dr["Type"].ToString());
                if (!(dr["Length"] is DBNull))
                    field.Length = dr["Length"].ToString();
                if (!(dr["IsNullable"] is DBNull))
                    field.IsNullable = dr["IsNullable"].ToString() == "True";
                if (!(dr["Cansearchable"] is DBNull))
                    field.Cansearchable = dr["Cansearchable"].ToString() == "True";
                if (!(dr["Format"] is DBNull))
                    field.Format = (FieldFormat)Enum.Parse(typeof(FieldFormat), dr["Format"].ToString());
                if (!(dr["LookupEntityName"] is DBNull))
                    field.LookupEntityName = dr["LookupEntityName"].ToString();
                if (!(dr["IsPrimaryAtt"] is DBNull))
                    field.IsPrimaryAtt = dr["IsPrimaryAtt"].ToString() == "True";

                if (!(dr["IsGlobalPicklist"] is DBNull))
                    field.IsGlobalPicklist = dr["IsGlobalPicklist"].ToString() == "True";
                if (!(dr["GlobalPicklist"] is DBNull))
                    field.GlobalPicklist = dr["GlobalPicklist"].ToString();
                if (!(dr["LookupPrimaryAtt"] is DBNull))
                    field.LookupPrimaryAtt = dr["LookupPrimaryAtt"].ToString();
                if (!(dr["AttributeWidth"] is DBNull))
                    field.AttributeWidth = dr["AttributeWidth"].ToString();
                if (!(dr["ViewOrderBy"] is DBNull))
                    field.ViewOrderBy = dr["ViewOrderBy"].ToString();
                fields.Add(field.Name, field);
            }
            return fields;
        }

        
        /// <summary>
        /// 根据视图中配置的存储过程，获取字段。（默认SYS_ViewAttCommon获取实体所有字段）
        /// </summary>
        /// <param name="ViewName"></param>
        /// <returns></returns>
        public Dictionary<string, Field> GetViewAllFields(string ViewName)
        {

            Dictionary<string, Field> fields = new Dictionary<string, Field>();
            DataTable dt = EntityDal.GetAttributeMapBySP(ViewName);
            foreach (DataRow dr in dt.Rows)
            {
                Field field = new Field();
                if (!(dr["Name"] is DBNull))
                    field.Name = dr["Name"].ToString().ToLower();
                if (!(dr["DisplayName"] is DBNull))
                    field.DisplayName = dr["DisplayName"].ToString();
                if (!(dr["EntityName"] is DBNull))
                    field.EntityName = dr["EntityName"].ToString();
                if (!(dr["Type"] is DBNull))
                    field.Type = (FieldType)Enum.Parse(typeof(FieldType), dr["Type"].ToString());
                if (!(dr["Length"] is DBNull))
                    field.Length = dr["Length"].ToString();
                if (!(dr["IsNullable"] is DBNull))
                    field.IsNullable = dr["IsNullable"].ToString() == "True";
                if (!(dr["Cansearchable"] is DBNull))
                    field.Cansearchable = dr["Cansearchable"].ToString() == "True";
                if (!(dr["Format"] is DBNull))
                    field.Format = (FieldFormat)Enum.Parse(typeof(FieldFormat), dr["Format"].ToString());
                if (!(dr["LookupEntityName"] is DBNull))
                    field.LookupEntityName = dr["LookupEntityName"].ToString();
                if (!(dr["IsPrimaryAtt"] is DBNull))
                    field.IsPrimaryAtt = dr["IsPrimaryAtt"].ToString() == "True";

                if (!(dr["IsGlobalPicklist"] is DBNull))
                    field.IsGlobalPicklist = dr["IsGlobalPicklist"].ToString() == "True";
                if (!(dr["GlobalPicklist"] is DBNull))
                    field.GlobalPicklist = dr["GlobalPicklist"].ToString();
                if (!(dr["LookupPrimaryAtt"] is DBNull))
                    field.LookupPrimaryAtt = dr["LookupPrimaryAtt"].ToString();
                if (!(dr["AttributeWidth"] is DBNull))
                    field.AttributeWidth = dr["AttributeWidth"].ToString();
                if (!(dr["ViewOrderBy"] is DBNull))
                    field.ViewOrderBy = dr["ViewOrderBy"].ToString();
                fields.Add(field.Name, field);
            }
            return fields;
        }
                
        public Dictionary<string, List<OptionSet>> GetEntityOptions(string ViewName = null)
        {
            string key = "";
            Dictionary<string, List<OptionSet>> dic = new Dictionary<string, List<OptionSet>>();
            List<OptionSet> options = new List<OptionSet>();
            DataTable dt = EntityDal.GetStringMapData(ViewName);
            foreach (DataRow dr in dt.Rows)
            {
                if (key != dr["Name"].ToString().ToLower())
                {
                    if (key == "")
                    {
                        key = dr["Name"].ToString().ToLower();
                    }
                    else
                    {
                        dic.Add(key, options);
                        key = dr["Name"].ToString().ToLower();
                        options = new List<OptionSet>();
                    }
                    options.Add(new OptionSet { Value = int.Parse(dr["Value"].ToString()), Text = dr["Text"].ToString() });
                }
                else
                {
                    options.Add(new OptionSet { Value = int.Parse(dr["Value"].ToString()), Text = dr["Text"].ToString() });
                }
            }

            if (options != null)
                dic.Add(key, options);
            return dic;
        }

        public List<ViewModel> GetViewsData()
        {
            List<ViewModel> vlist =new List<ViewModel>();
            DataTable dt = EntityDal.GetViewMapData();
            foreach (DataRow row in dt.Rows)
            {
                if (row["ViewName"].ToString().ToLower() != "lookupview")
                {
                    vlist.Add(new ViewModel(row["ViewName"].ToString(), row["ViewDisplayName"].ToString(), (int)row["ClientType"]));
                }
            }
            return vlist;
        }

        public Privilege GetPrivilege(Guid SystemUserId)
        {
            Privilege p = new Privilege();
            DataTable dt = new PrivilegeDAL().GetSecurityLevel(this.EntityName, SystemUserId);
            foreach (DataRow dr in dt.Rows)
            {
                switch ((AccessRight)dr["AccessLevel"])
                {
                    case AccessRight.READ:
                        p.READ = (DepthMask)dr["SecurityLevel"];
                        break;
                    case AccessRight.WRITE:
                        p.WRITE = (DepthMask)dr["SecurityLevel"];
                        break;
                    case AccessRight.CREATE:
                        p.CREATE = (DepthMask)dr["SecurityLevel"];
                        break;
                    case AccessRight.DELETE:
                        p.DELETE = (DepthMask)dr["SecurityLevel"];
                        break;
                    case AccessRight.ASSIGN:
                        p.ASSIGN = (DepthMask)dr["SecurityLevel"];
                        break;
                    default:
                        break;
                }
            }
            return p;
        }

        public List<string> GetOprivilege(Guid SystemUserId)
        {
            List<string> FunctionPrivilege = new List<string>();
            DataTable dt = new PrivilegeDAL().GetOprivilege(SystemUserId);
            foreach (DataRow dr in dt.Rows)
            {
                FunctionPrivilege.Add(dr["Code"].ToString());
            }
            return FunctionPrivilege;
        }




    }

    

    #region 标准CURD对象
    /// <summary>
    /// 标准CURD对象
    /// </summary>
    public class CURD
    {

        private readonly SqlDatabase sqldb = new SqlDatabase(Config.TulingBuyCrmConnectString);

        private string EntityName;
        private string Prefix;
        public Dictionary<string, Field> Fields;

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="entityName"></param>
        public CURD(string entityName)
        {
            if (string.IsNullOrWhiteSpace(entityName))
                throw new Exception(string.Format("EntityName Is NullOrWhiteSpace! "));
            this.Prefix = GetPrefix();
            this.EntityName = entityName;
            this.Fields = GetEntityFields();

        }


        /// <summary>
        /// 更新记录
        /// </summary>
        /// <param name="data">jsonEntity</param>
        public string Update(Dictionary<string, object> dicValue)
        {

            string commandText = SqlConvert.ToUpdateCommnad(this.EntityName, dicValue, this.Fields);
            sqldb.ExecuteNonQuery(CommandType.Text, commandText);

            return dicValue[this.EntityName + "id"].ToString();


        }


        /// <summary>
        /// 删除记录
        /// </summary>
        /// <param name="id">记录Id</param>
        public void Delete(Guid id)
        {

            string commandText = SqlConvert.ToDeleteCommand(this.EntityName, id);
            sqldb.ExecuteNonQuery(CommandType.Text, commandText);


        }



        #region 私有方法
        private Dictionary<string, Field> GetEntityFields(string ViewName = null)
        {
            Dictionary<string, Field> fields = new Dictionary<string, Field>();
            string commandText = "";
            SqlParameter[] pams;
            if (string.IsNullOrEmpty(ViewName))
            {

                commandText = string.Format(@"--查询实体字段定义
                                                SELECT  Name ,
                                                        DisplayName ,
                                                        Type ,
                                                        Length ,
                                                        IsNullable ,
                                                        Cansearchable ,
                                                        Format ,
                                                        LookupEntityName ,
                                                        IsPrimaryAtt ,
                                                        IsGlobalPicklist ,
                                                        GlobalPicklist ,
                                                        LookupPrimaryAtt,
                                                        NULL as AttributeWidth,
                                                        NULL as ViewOrderBy
                                                FROM    dbo.AttributeMap WITH(NOLOCK)
                                                WHERE   EntityName = @entityName");
                pams = new SqlParameter[]{
	                new SqlParameter("@entityName",this.EntityName)           
                };
            }
            else
            {
                commandText = string.Format(@"--查询实体字段定义
                                          SELECT Name ,
                                                DisplayName ,
                                                Type ,
                                                Length ,
                                                IsNullable ,
                                                Cansearchable ,
                                                Format ,
                                                LookupEntityName ,
                                                IsPrimaryAtt ,
                                                IsGlobalPicklist ,
                                                GlobalPicklist ,
                                                LookupPrimaryAtt,
												vm.AttributeWidth,
                                                vm.ViewOrderBy
                                         FROM   dbo.AttributeMap am WITH ( NOLOCK )
                                                INNER JOIN ViewAttMap vm WITH ( NOLOCK ) ON vm.AttributeName = am.name
                                                                                         AND vm.EntityName = am.EntityName
                                                                                         AND ViewName = @viewName
                                         WHERE  am.EntityName = @entityName
                                         ORDER BY vm.AttributeOrder ");
                pams = new SqlParameter[]{
	                new SqlParameter("@entityName",this.EntityName),
                    new SqlParameter("@viewName",ViewName)
                };
            }
            DbCommand cmd = sqldb.GetSqlStringCommand(commandText);
            cmd.Parameters.AddRange(pams);
            using (IDataReader reader = sqldb.ExecuteReader(cmd))
            {
                while (reader.Read())
                {
                    Field field = new Field();

                    if (!(reader["Name"] is DBNull))
                        field.Name = reader["Name"].ToString().ToLower();
                    if (!(reader["DisplayName"] is DBNull))
                        field.DisplayName = reader["DisplayName"].ToString();
                    if (!(reader["Type"] is DBNull))
                        field.Type = (FieldType)Enum.Parse(typeof(FieldType), reader["Type"].ToString());

                    if (!(reader["Length"] is DBNull))
                        field.Length = reader["Length"].ToString();
                    // int.Parse(reader["Length"].ToString());
                    if (!(reader["IsNullable"] is DBNull))
                        field.IsNullable = reader["IsNullable"].ToString() == "True";

                    if (!(reader["Cansearchable"] is DBNull))
                        field.Cansearchable = reader["Cansearchable"].ToString() == "True";

                    if (!(reader["Format"] is DBNull))
                        field.Format = (FieldFormat)Enum.Parse(typeof(FieldFormat), reader["Format"].ToString());
                    if (!(reader["LookupEntityName"] is DBNull))
                        field.LookupEntityName = reader["LookupEntityName"].ToString();
                    if (!(reader["IsPrimaryAtt"] is DBNull))
                        field.IsPrimaryAtt = reader["IsPrimaryAtt"].ToString() == "True";

                    if (!(reader["IsGlobalPicklist"] is DBNull))
                        field.IsGlobalPicklist = reader["IsGlobalPicklist"].ToString() == "True";
                    if (!(reader["GlobalPicklist"] is DBNull))
                        field.GlobalPicklist = reader["GlobalPicklist"].ToString();
                    if (!(reader["LookupPrimaryAtt"] is DBNull))
                        field.LookupPrimaryAtt = reader["LookupPrimaryAtt"].ToString();
                    if (!(reader["AttributeWidth"] is DBNull))
                        field.AttributeWidth = reader["AttributeWidth"].ToString();
                    if (!(reader["ViewOrderBy"] is DBNull))
                        field.ViewOrderBy = reader["ViewOrderBy"].ToString();
                    fields.Add(field.Name, field);
                }

            }
            return fields;
        }

        private string DataTableToJsonEntity(DataTable dt, string[] columns)
        {


            JObject jo = new JObject();
            foreach (var item in columns)
            {
                switch (this.Fields[item].Type)
                {
                    case FieldType.key:
                    case FieldType.nvarchar:
                    case FieldType.ntext:
                    case FieldType.image:
                        {
                            if (dt.Rows[0][item] is DBNull)
                                jo.Add(item, null);
                            else
                                jo.Add(item, dt.Rows[0][item].ToString());

                            break;
                        }
                    case FieldType.datetime:
                        {
                            if (dt.Rows[0][item] is DBNull)
                                jo.Add(item, null);
                            else
                                jo.Add(item, DateTime.Parse(dt.Rows[0][item].ToString()).ToString("yyyy-MM-dd HH:mm:ss"));

                            break;
                        }
                    case FieldType.date:
                        {

                            if (dt.Rows[0][item] is DBNull)
                                jo.Add(item, null);
                            else
                                jo.Add(item, DateTime.Parse(dt.Rows[0][item].ToString()).ToString("yyyy-MM-dd"));

                            break;
                        }
                    case FieldType.picklist:
                    case FieldType.@int:
                        {
                            if (dt.Rows[0][item] is DBNull)
                                jo.Add(item, null);
                            else
                                jo.Add(item, int.Parse(dt.Rows[0][item].ToString()));

                            break;
                        }
                    case FieldType.bit:
                        {
                            if (dt.Rows[0][item] is DBNull)
                                jo.Add(item, null);
                            else
                                jo.Add(item, dt.Rows[0][item].ToString() == "True");
                            break;
                        }
                    case FieldType.@float:
                        {
                            if (dt.Rows[0][item] is DBNull)
                                jo.Add(item, null);
                            else
                                jo.Add(item, double.Parse(dt.Rows[0][item].ToString()));
                            break;
                        }
                    case FieldType.lookup:
                        {
                            if (dt.Rows[0][item] is DBNull)
                                jo.Add(item, null);
                            else
                            {
                                var jef = new JObject();
                                jef.Add("Id", dt.Rows[0][item].ToString());
                                jef.Add("Name", dt.Rows[0][item + "Name"].ToString());
                                jef.Add("EntityName", this.Fields[item].LookupEntityName);
                                jo.Add(item, jef);
                            }
                            break;
                        }
                }

            }
            return JsonConvert.SerializeObject(jo);
        }

        public string DataTableToJsonEntityList(DataTable dt, string[] columns, int length, int pageNum, int pageSize)
        {
            JObject listInfo = new JObject();

            listInfo.Add("Total", length);
            listInfo.Add("Size", pageSize);
            listInfo.Add("Index", pageNum);

            JArray ja = new JArray();
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                JObject jo = new JObject();
                foreach (var item in columns)
                {
                    switch (this.Fields[item].Type)
                    {
                        case FieldType.key:
                        case FieldType.nvarchar:
                        case FieldType.ntext:
                            {
                                if (dt.Rows[i][item] is DBNull)
                                    jo.Add(item, null);
                                else
                                    jo.Add(item, dt.Rows[i][item].ToString());

                                break;
                            }
                        case FieldType.datetime:
                            {
                                if (dt.Rows[i][item] is DBNull)
                                    jo.Add(item, null);
                                else
                                    jo.Add(item, DateTime.Parse(dt.Rows[i][item].ToString()).ToString("yyyy-MM-dd HH:mm:ss"));

                                break;
                            }
                        case FieldType.date:
                            {

                                if (dt.Rows[i][item] is DBNull)
                                    jo.Add(item, null);
                                else
                                    jo.Add(item, DateTime.Parse(dt.Rows[i][item].ToString()).ToString("yyyy-MM-dd"));

                                break;
                            }
                        case FieldType.picklist:
                        case FieldType.@int:
                            {
                                if (dt.Rows[i][item] is DBNull)
                                    jo.Add(item, null);
                                else
                                    jo.Add(item, int.Parse(dt.Rows[i][item].ToString()));

                                break;
                            }
                        case FieldType.bit:
                            {
                                if (dt.Rows[i][item] is DBNull)
                                    jo.Add(item, null);
                                else
                                    jo.Add(item, dt.Rows[i][item].ToString() == "True");
                                break;
                            }
                        case FieldType.@float:
                            {
                                if (dt.Rows[i][item] is DBNull)
                                    jo.Add(item, null);
                                else
                                    jo.Add(item, double.Parse(dt.Rows[i][item].ToString()));
                                break;
                            }
                        case FieldType.lookup:
                            {
                                if (dt.Rows[i][item] is DBNull)
                                    jo.Add(item, null);
                                else
                                {
                                    var jef = new JObject();
                                    jef.Add("Id", dt.Rows[i][item].ToString());
                                    jef.Add("Name", dt.Rows[i][item + "Name"].ToString());
                                    jef.Add("EntityName", this.Fields[item].LookupEntityName);
                                    jo.Add(item, jef);
                                }
                                break;
                            }
                    }

                }
                ja.Add(jo);
            }
            listInfo.Add("List", ja);
            return JsonConvert.SerializeObject(listInfo);
        }




        private string GetPrefix()
        {
            string prefix = null;
            string commandText = @"--查询前缀配置
                                    SELECT  Value
                                    FROM    dbo.Parameter
                                    WHERE   Name = 'prefix'";
            using (IDataReader sqlReader = sqldb.ExecuteReader(CommandType.Text, commandText))
            {
                while (sqlReader.Read())
                {
                    prefix = sqlReader["Value"].ToString();
                }
            }
            if (string.IsNullOrWhiteSpace(prefix))
                prefix = null;
            return prefix;
        }

        public List<List<string>> GetColumnsByView(string ViewName)
        {
            List<List<string>> returns = new List<List<string>>();

            List<string> columns = new List<string>();
            List<string> lookup = new List<string>();
            string commandText = string.Format(@"--查找视图列
                                   SELECT  AttributeName 
                                   FROM    dbo.ViewAttMap
                                   WHERE   ViewName = @viewName AND
                                           EntityName =@entityName
                                   ORDER BY AttributeOrder ");
            SqlParameter[] pams = new SqlParameter[]{
	            new SqlParameter("@viewName",ViewName),
	            new SqlParameter("@entityName",this.EntityName)
            };
            DbCommand cmd = sqldb.GetSqlStringCommand(commandText);
            cmd.Parameters.AddRange(pams);
            using (IDataReader sqlReader = sqldb.ExecuteReader(cmd))
            {
                while (sqlReader.Read())
                {
                    if (this.Fields[sqlReader["AttributeName"].ToString().ToLower()].Type == FieldType.lookup)
                    {
                        lookup.Add((sqlReader["AttributeName"].ToString() + "Name").ToLower());
                    }
                    columns.Add(sqlReader["AttributeName"].ToString().ToLower());

                }
            }
            //默认添加ID列
            columns.Add((this.EntityName + "id").ToLower());
            returns.Add(columns);
            returns.Add(lookup);
            return returns;
        }

        private string GetFixFilterByView(string ViewName)
        {
            string where = null;

            string commandText = string.Format(@"--查找视图筛选条件
                                                SELECT  ViewFilter
                                                FROM    ViewMap
                                                WHERE   EntityName = @entityName
                                                        AND ViewName = @viewName ");
            SqlParameter[] pams = new SqlParameter[]{ 
	            new SqlParameter("@entityName",this.EntityName),
                new SqlParameter("@viewName",ViewName)
            };
            DbCommand cmd = sqldb.GetSqlStringCommand(commandText);
            cmd.Parameters.AddRange(pams);
            using (IDataReader sqlReader = sqldb.ExecuteReader(cmd))
            {
                while (sqlReader.Read())
                {
                    where = sqlReader["ViewFilter"].ToString();
                }
            }

            return where;
        }


        #endregion
    }
    #endregion



}